v-if 用於條件的方式渲染一個區塊,當指令的內容回傳為真值時會產生結構內容。
// html
<div id="app">
<h4>v-if, v-else</h4>
<div class="alert alert-success" v-if="isSuccess">成功!</div>
<div class="alert alert-danger" v-else>失敗!</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="isSuccess" v-model="isSuccess">
<label class="form-check-label" for="isSuccess">啟用元素狀態</label>
</div>
<h4>v-else-if</h4>
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active': link === 'a'}" @click="link = 'a'">標題一</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active': link === 'b'}" @click="link = 'b'">標題二</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active': link === 'c'}" @click="link = 'c'">標題三</a>
</li>
</ul>
<div class="content">
<div v-if="link === 'a'">A</div>
<div v-else-if="link === 'b'">B</div>
<div v-else-if="link === 'c'">C</div>
</div>
</div>
// JS
var app = new Vue({
el: '#app',
data: {
isSuccess: true,
link: 'a',
},
});
v-show
與 v-if
同樣是用來切換物件的呈現,但兩者有差異:
v-if
會完整移除 DOM 元素,使其從 HTML 結構上消失。當使用此方法切換 Vue 元件時,元件的生命週期會重新計算。v-show
是將物件加上 display: none
,讓物件從視覺上不可見。此方法運行結果與上述相同,但元素是套用 display: none
作為顯示上的切換。
v-if
、v-show
怎麼選擇?v-if
,如果則否可用 v-show
。// html
<div id="app">
<div class="alert alert-success" v-show="isSuccess">成功!</div>
<div class="alert alert-danger" v-show="!isSuccess">失敗!</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="isSuccess" v-model="isSuccess">
<label class="form-check-label" for="isSuccess">啟用元素狀態</label>
</div>
</div>
// JS
var app = new Vue({
el: '#app',
data: {
isSuccess: true,
},
});
請使用開發者工具檢視畫面上的「成功、失敗」區塊,可以發現是使用 display: none 的方式隱藏,而不是移除整個 DOM 結構。
課程範例
v-for
可以針對一組陣列或物件進行渲染,指令中會使用 (item, key) in array
的語法,其中:
範例為陣列、物件搭配迴圈的方式:
// html
<div id="app">
<h4>陣列與物件的迴圈</h4>
<ul>
<li v-for="(item, key) in arrayData">
{{ key }} - {{ item.name }} {{ item.age }} 歲
</li>
<li v-for="(item, key) in objectData">
{{ key }} - {{ item.name }} {{ item.age }} 歲
</li>
</ul>
</div>
// JS
var app = new Vue({
el: '#app',
data: {
arrayData: [
{
name: 'Gary',
age: 35
},
{
name: 'Tony',
age: 28
},
{
name: 'Jack',
age: 33
}
],
objectData: {
casper: {
name: 'Gary',
age: 35
},
ray: {
name: 'Tony',
age: 32
},
gonsakon: {
name: 'Jack',
age: 33
}
},
}
});
v-for="(item, key) in array"
0, 1, 2...
,物件索引則為屬性名稱由於 v-for 在運作上是採用快速替換的形式。因此,有部分元素會沒有完整的被替換,可參考以下範例:
情境,當 input 輸入內容後,按下反轉陣列時:
新版的 Vue 相關開發工具中,都會強烈建議加上 key
。
// html
<div id="app">
<h4>缺少 key</h4>
<ul>
<li v-for="(item, key) in arrayData" >
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
<h4>加上 key</h4>
<ul>
<li v-for="(item, key) in arrayData" :key="item.age">
{{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
</li>
</ul>
<button class="btn btn-outline-primary" @click="reverseArray">反轉陣列</button>
</div>
// JS
var app = new Vue({
el: '#app',
data: {
arrayData: [
{
name: 'Gary',
age: 35
},
{
name: 'Tony',
age: 28
},
{
name: 'Jack',
age: 33
}
]
},
methods: {
reverseArray: function () {
this.arrayData.reverse()
console.log(this.arrayData)
},
}
});
當渲染陣列資料卻不便產生新的標籤時,可以搭配 <template>
標籤做使用,此方法即可在產生 DOM 結構時不產生額外的標籤。另外 template
標籤也同樣可用於 v-for
上
// html
<div id="app">
<h4>Template 的運用</h4>
<table class="table">
<tbody>
<template v-for="(item, key) in arrayData">
<tr>
<td>{{ key }}</td>
<td>{{ item.name }}</td>
<td>{{ item.age }} 歲</td>
</tr>
</template>
</tbody>
</table>
</div>
// JS
var app = new Vue({
el: '#app',
data: {
arrayData: [
{
name: 'Gary',
age: 35
},
{
name: 'Tony',
age: 28
},
{
name: 'Jack',
age: 33
}
]
},
methods: {
reverseArray: function () {
this.arrayData.reverse()
console.log(this.arrayData)
},
}
});
可以使用 template 標籤替代原有的 HTML 標籤,而 template 標籤是不會被輸出的。
課程範例
為了避免不要的錯誤,Vue.js 的規範中建議不要將 v-for 與 v-if 混合使用。搭配進階工具如 Vue Cli 及 ESLint 時,兩者混合使用會跳出錯誤。
// html
<div id="app">
<table class="table">
<tbody>
<template v-for="(item, key) in arrayData">
<tr v-if="item.age > 30">
<td>{{ key }}</td>
<td>{{ item.name }}</td>
<td>{{ item.age }} 歲</td>
</tr>
</template>
</tbody>
</table>
</div>
// JS
var app = new Vue({
el: '#app',
data: {
arrayData: [
{
name: 'Gary',
age: 35
},
{
name: 'Tony',
age: 28
},
{
name: 'Jack',
age: 33
}
],
},
});
盡可能將 v-if 與 v-for 用不同的標籤呈現
課程範例